const Service = require('egg').Service;
const _ = require('lodash')

class PrizeService extends Service {
  commonCondition(data, type) {
    const c1 = {};
    const c2 = {};
    const c3 = [];


    c3.push({
      $skip: (data.pageIndex - 1) * data.pageSize,
    });

    c3.push({
      $limit: data.pageSize,
    });

    // 活动id
    if (data.campaign_id) {
      c1.campaign_id = this.app.__mongoose.Types.ObjectId(data.campaign_id);
    }

    // 奖品类型
    if (data.award_type) {
      c1.award_type = data.award_type;
    }

    // 奖品id
    if (data.award_id) {
      c1.award_id = this.app.__mongoose.Types.ObjectId(data.award_id);
    }

    // 时间
    if (data.start_time && data.end_time) {
      c1.create_time = {
        $gte: new Date(data.start_time),
        $lte: new Date(data.end_time),
      };
    }
    // 中奖记录状态
    if (data.status) {
      c1.status = data.status;
    }

    // 产品类型
    if (data.product_type) {
      if (type) {
        c2.pcode = data.product_type;
      } else {
        c2['campaign.pcode'] = data.product_type;
      }
    }

    return [c1, c2, c3];
  }

  async totalAmount(data) {
    const c = this.commonCondition(data);

    const totalAmount = await this.app.model.Prize.aggregate([{
      $match: c[0],
    }, {
      $lookup: {
        from: 'campaigns',
        localField: 'campaign_id',
        foreignField: '_id',
        as: 'campaign',
      },
    }, {
      $match: c[1],
    }, {
      $group: {
        _id: { award_type: '$award_type', campaign_id: '$campaign_id' },
        total_amount: { $sum: '$award_unit_price' },
      },
    }]);

    return totalAmount;
  }

  async list(data) {
    const c = this.commonCondition(data);

    const other = await this.app.model.Prize.aggregate([{
        $match: c[0],
      }, {
        $lookup: {
          from: 'campaigns',
          localField: 'campaign_id',
          foreignField: '_id',
          as: 'campaign',
        },
      },
      {
        $match: c[1],
      },
      ...c[2],
    ]);

    let userIds = other.map((item) => item.user_id)

    let users = await this.app.model.User.find({ _id: { $in: userIds } })


    other.map(function(item) {
      let user = _.filter(users, (o) => item.user_id.toString() == o._id.toString())
      item.user = user
    })

    return other;
  }

  async total(data) {
    const c = this.commonCondition(data);

    const total = await this.app.model.Prize.aggregate([{
        $match: c[0],
      }, {
        $lookup: {
          from: 'campaigns',
          localField: 'campaign_id',
          foreignField: '_id',
          as: 'campaign',
        },
      },
      {
        $match: c[1],
      },
      {
        $count: 'total',
      },
    ]);

    return total;
  }

  async history(data) {
    const c = {};
    c.status = data.status;

    if (data.campaign_id) {
      c.campaign_id = this.app.__mongoose.Types.ObjectId(data.campaign_id);
    }

    if (data.award_type) {
      c.award_type = data.award_type;
    }

    if (data.start_time && data.end_time) {
      c.grant_time = {
        $gte: new Date(data.start_time),
        $lte: new Date(data.end_time),
      };
    }

    var round = function(val, places) {
      var p = {};
      var divider = Math.pow(10, places);
      p["$divide"] = [];
      var newval = { $add: [{ "$multiply": [val, divider] }, .5] }
      var sub = { "$subtract": [newval, { "$mod": [newval, 1] }] };
      p["$divide"].push(sub);
      p["$divide"].push(divider);
      return p;
    }

    const history = await this.app.model.Prize.aggregate([{
        $match: c,
      }, {
        $group: {
          _id: { campaign_id: '$campaign_id', award_type: '$award_type', award_id: '$award_id', award_name: '$award_name', status: '$status' },
          amount: { $sum: '$award_unit_price' },
          quantities: { $sum: '$award_quantities' },
        },
      }, {
        $lookup: {
          from: 'campaigns',
          localField: '_id.campaign_id',
          foreignField: '_id',
          as: 'campaign',
        },
      }, {
        $match: {
          'campaign.pcode': data.product_type,
        },
      }, {
        $sort: {
          'campaign.title': 1,
          '_id.award_name': 1,
        },
      },
      {
        $skip: (data.pageIndex - 1) * data.pageSize,
      },
      {
        $limit: parseInt(data.pageSize),
      },
      {
        $project: {
          amount: round('$amount', 2),
          quantities: 1,
          campaign: 1
        }
      }
    ]);

    const historyTotal = await this.app.model.Prize.aggregate([{
        $match: c,
      }, {
        $group: {
          _id: { campaign_id: '$campaign_id', award_type: '$award_type', award_id: '$award_id', award_name: '$award_name', status: '$status' },
          amount: { $sum: '$award_unit_price' },
          quantities: { $sum: '$award_quantities' },
        },
      }, {
        $lookup: {
          from: 'campaigns',
          localField: '_id.campaign_id',
          foreignField: '_id',
          as: 'campaign',
        },
      }, {
        $match: {
          'campaign.pcode': data.product_type,
        },
      },
      {
        $count: 'total',
      },
    ]);

    const quantitiesAndAmount = await this.app.model.Prize.aggregate([{
        $match: c,
      }, {
        $lookup: {
          from: 'campaigns',
          localField: 'campaign_id',
          foreignField: '_id',
          as: 'campaign',
        },
      }, {
        $match: {
          'campaign.pcode': data.product_type,
        },
      },
      {
        $group: {
          _id: '',
          totalAmount: { $sum: '$award_unit_price' },
          totalQuantities: { $sum: '$award_quantities' },
        },
      },
    ]);


    return [history, historyTotal, quantitiesAndAmount];
  }

  async mark(data) {
    const c1 = {};

    c1.campaign_id = data.campaign_id;
    c1.award_type = data.award_type;
    c1.status = '00';

    const c2 = {};

    c2.campaign_id = this.app.__mongoose.Types.ObjectId(data.campaign_id);
    c2.award_type = data.award_type;
    c2.status = '00';

    if (data.start_time && data.end_time) {
      c1.create_time = {
        $gte: data.start_time,
        $lte: data.end_time,
      };

      c2.create_time = {
        $gte: new Date(data.start_time),
        $lte: new Date(data.end_time),
      };
    }

    // 数据
    const marked = await this.app.model.Prize.find(c1);

    // 总金额
    const amount = await this.app.model.Prize.aggregate([{
      $match: c2,
    }, {
      $group: {
        _id: '$campaign_id',
        totalAmount: { $sum: '$award_unit_price' },
      },
    }]);

    // 更新状态
    const ret = await this.app.model.Prize.updateMany(c1, {
      $set: {
        status: '10',
        update_time: new Date(),
        grant_time: new Date(),
      },
    });

    return [marked, amount];
  }
}

module.exports = PrizeService;
